<pre class='metadata'>
Title: Isolated Contexts
Shortname: isolated-contexts
Level: 1
Group: wicg
Status: w3c/CG-DRAFT
ED: https://wicg.github.io/isolated-web-apps/isolated-contexts.html
Repository: https://github.com/WICG/isolated-web-apps

Editor: Robbie McElrath 139758, Google LLC https://google.com, rmcelrath@google.com

Abstract:
  This specification defines "isolated contexts", which allow user agent
  implementers and specification authors to enable certain features only when
  minimum standards of isolation and integrity are met.

Markup Shorthands: markdown yes
</pre>

<pre class="link-defaults">
spec:csp3; type:dfn; for:/; text:csp list
spec:ecmascript; type:dfn; for:ECMAScript; text:realm
spec:fetch; type:dfn; for:/; text:response
spec:fetch; type:dfn; text:fetch params
spec:fetch; type:dfn; for:fetch params; text:request
spec:fetch; type:dfn; text:main fetch
spec:html; type:dfn; for:environment settings object; text:cross-origin isolated capability
spec:html; type:dfn; text:browsing context group
spec:html; type:dfn; text:concrete
spec:html; type:dfn; for:/; text:origin
spec:html; type:dfn; for:environment settings object; text:origin
spec:infra; type:dfn; for:list; text:for each
spec:infra; type:dfn; text:user agent
spec:url; type:dfn; for:/; text:url
spec:webidl; type:dfn; text:namespace
</pre>
<pre class="anchors">
urlPrefix: https://w3c.github.io/webappsec-csp/; spec:CSP3
    type: abstract-op
        text: Get fetch directive fallback list; url: #directive-fallback-list
urlPrefix: https://w3c.github.io/trusted-types/dist/spec/; spec:trusted-types
    type: dfn
        text: require-trusted-types-for-directive
</pre>
<pre class=biblio>
{
  "strict-csp": {
      "href": "https://web.dev/strict-csp/",
      "title": "Mitigate cross-site scripting (XSS) with a strict Content Security Policy (CSP)",
      "authors": [ "Lukas Weichselbaum" ],
      "date": "15 March 2021"
  },
  "securer-contexts": {
    "authors": [ "Mike West" ],
    "href": "https://github.com/mikewest/securer-contexts",
    "title": "Securer Contexts"
  }
}
</pre>

# Introduction # {#introduction}

Throughout its existence the web has been evolved into an increasingly capable
application platform. [=Secure Contexts=] formalize transport security,
[=environment settings object/cross-origin isolated capability|Cross Origin
Isolation=] mitigates side-channel attacks, and browsers and operating systems
have experimented with permission interfaces based on selecting particular
files and devices to make access more scoped and understandable to users. Each
of these advancements either improved the safety guarantees of the web
platform, or guided users towards a more accurate expection of a page's
behavior, and unlocked new classes of capabilities that could be brought safely
to the web.

Despite these advancements, there are some APIs that still cannot safely be
exposed to the web because they violate the web's security primitives in a way
that cannot reasonably be addressed, or cannot be explained clearly enough for
users to make an informed decision about whether or not to grant a site access
to them. If the platform cannot prove that exposing an API to a particular site
is safe, then trust must derive from external attestations.

Any assertion about the safety or behavior of a page requires knowing the
contents and behavior of the page; attestations are only meaningful if the code
that was vouched for is the same code being executed. Because of this, any
system that delegates trust decisions must be able to verify the integrity of
the code it is running &mdash; it must know that it matches the code that was
delegated trust.

Additionally, capabilities that don't fit within the web's current security
model have the potential to pose a risk to other web content. This risk is
bidirectional: sandbox-piercing capabilities could be used to attack other
sites, and having access to powerful capabilities makes a site a more
attractive target for bad actors. To mitigate these risks, any content that is
granted access to a capability through the mechanisms described in this
specification must be isolated from a user's normal browsing session.

This specification defines <dfn>Isolated Contexts</dfn>, which are environments
that meet a minimum standard of integrity and isolation, and provide a means of
auditing web content for the purpose of trustworthiness attestation, and
isolate this content from the rest of the user's browsing data.

While this specification focuses on user-agent provided capabilities, Isolated
Contexts could be beneficial for any web page functionality whose threat model
isn't satisfied by the web's security model. For example, the threat model of
some end-to-end encrypted chat applications includes server compromise, which
is not protected against by the web today. The auditability and attestation
enabled by Isolated Contexts could allow these applications to have confidence
in the integrity and providence of the code they are running.


# Isolated Contexts # {#isolated-context-info}

[=Isolated Contexts=] are defined through a series of [[#monkey]] to existing
specifications.

Integrity is verified through a combination of strict [[CSP]], which ensures
cross-origin executable content cannot be loaded, and an integrity verification
algorithm, which is an abstract mechanism to validate content loaded within a
page. This specification does not mandate a specific validation approach, it
only defines how one would be used to determine if an environment is an
Isolated Context.


## Which APIs should require an Isolated Context? ## {#which-apis}

As few as possible. Any API that can only be exposed to Isolated Contexts very
likely violates at least one
<a href="https://w3ctag.github.io/design-principles/#basic-principles">
design principle</a> of the web, most commonly that
<a href="https://w3ctag.github.io/design-principles/#safe-to-browse">
it should be safe to visit a web page</a>. Before requiring an Isolated Context
to use an API, consider the following questions:

1.  Is a new Web Platform API the only way to address the problems this API is
    trying to solve? Web Extensions and native applications have their place.
1.  If a capability cannot be communicated clearly to users, is there another
    way to solve the problem that would be more understandable to users, and
    allow them to make informed decisions about what content can access it?
1.  Can the scope of the API be reduced such that it no longer poses an
    unacceptable risk if exposed to an average web page?

If no alternative can be found, requiring an API to run within an Isolated
Context can be considered as a last resort.

Part of what makes the web such a unique and successful platform is its lack of
gatekeepers. Anyone can purchase a domain name and host their content without
anyone else's approval, and with full access to the Web Platform's API surface;
everyone has equal footing. The security guarantees provided by Isolated
Contexts enable auditability, which in turn enables attestation. The safety
provided by attestation, either by the browser vendor or a third-party, is the
main reason an API would be restricted to Isolated Contexts. Parties providing
attestation services have the potential to become gatekeepers to the Web
Platform, which is not a desirable direction for the platform to move. Browser
vendors must be extremely selective about which APIs they allow in Isolated
Contexts; changing an API so it can be used in a Secure Context should be
strongly preferred whenever possible.


## UI Treatment ## {#ui-treatment}

This specification focuses on the technical requirements needed to achieve
integrity and isolation, but if Isolated Contexts are being used to enable
powerful capabilities, it is also critical to not violate user expectations.

Users trust the web because they've been taught that web pages are safe, have
limited access to their device, and that they are in control of this access. All
APIs on the Web Platform have been carefully designed towards this end, with a
goal of ensuring that
<a href="https://w3ctag.github.io/design-principles/#safe-to-browse">
it should be safe to visit a web page</a>.

Browser vendors should consider whether capabilities restricted to Isolated
Contexts would violate a user's expectation of what a web page is capable of
doing. Violating these expectations would not only damage trust in the site, but
has the risk of damaging a user's trust in the Web Platform as a whole.

To mitigate this, steps should be taken by the user agent to convey to users
that content running within an Isolated Context is not typical web content. This
could involve an installation flow, or a Web App UI treatment.


# Monkey Patches # {#monkey}

This specification makes the following monkey patches to existing
specifications:

*   Patches to [[CSP]] will define the characteristics of a policy that's robust
    enough to meaningfully defend against attack, and enforce that cross-origin
    content cannot be loaded. It builds on what we've learned from explorations
    like [[strict-csp]] and [[securer-contexts]], pushing developers towards
    well-understood and valuable defenses.

*   Patches to [[HTML]] will define the ways in which those CSP characteristics,
    along with other security requirements, are evaluated within a given
    context, similar conceptually to [=secure context=] and [=environment
    settings object/cross-origin isolated capability=]. It will additionally
    define [=user agent=] properties needed to verify the integrity of an
    [=origin=]'s resources.

*   Patches to [[FETCH]] will add integrity verification to the [=fetch=]
    algorithm.

*   Patches to [[WEBIDL]] will define the `[IsolatedContext]` attribute, and
    the way it relies on the changes above to control the exposure of a given
    WebIDL construct.

*   Patches to [[STORAGE]] will define the double-keying requirements of
    [=Isolated Contexts=].


## Content Security Policy ## {#monkey-csp}

In [[CSP]], we'll define an algorithm for evaluating the strength of the
amalgamation of policies contained within a [=CSP list=]. We'll define a
few supporting algorithms as well, but [[#csp-injection-mitigation]]
is the core entry point CSP will expose to HTML.

### Does a policy meaningfully mitigate injection attacks? ### {#csp-injection-mitigation}

<div algorithm="meaningfully mitigates injection">
A [=CSP list=] |policies| is said to
<dfn for="CSP list" export local-lt="mitigate-injection">meaningfully
mitigate injection attacks</dfn> if the following algorithm returns
"`Meaningful`". Possible return values are "`Meaningful`" and
"`Not meaningful enough`".

<ol class="algorithm">
    1.  Let |meets object requirements|, |meets base requirements|,
        |meets script requirements|, |meets style requirements|,
        |meets subresource requirements|, and |meets trusted type requirements|
        be [=booleans=] whose values are `false`.

    1.  [=For each=] |policy| in |policies|:

        1.  If |policy|'s [=policy/disposition=] is not "`enforce`" or
            |policy|'s [=policy/source=] is not "`header`",
            [=iteration/continue=].

        1.  If |policy| [=policy/sufficiently mitigates plugins=], set
            |meets object requirements| to `true`. 

        1.  If |policy| [=policy/sufficiently mitigates relative URL manipulation=], set
            |meets base requirements| to `true`. 

        1.  If |policy| [=policy/sufficiently mitigates script execution=], set
            |meets script requirements| to `true`.

        1.  If |policy| [=policy/sufficiently mitigates style evaluation=], set
            |meets style requirements| to `true`. 

        1.  If |policy| [=policy/sufficiently blocks insecure subresources=], set
            |meets subresource requirements| to `true`.

        1.  If |policy| [=policy/sufficiently mitigates DOM sinks=], set
            |meets trusted type requirements| to `true`. 

    1.  Return "`Meaningful`" if |meets object requirements|,
        |meets base requirements|, |meets script requirements|,
        |meets style requirements|, |meets subresource requirements|, and
        |meets trusted type requirements| are all `true`.
    1. Return "`Not meaningful enough`".
</ol>
</div>

### Obtain the active directive for a type ### {#csp-active-directive}

<div algorithm="get active directive">
CSP defines a fallback chain for some directives which we need to account for
when evaluating a given policy. To <dfn abstract-op lt="obtain-directive">obtain
the active directive</dfn> given a [=policy=] |policy| and a |directive name|:

<ol class="algorithm">
    1.  Let |fallback chain| be the result of executing <a abstract-op>Get fetch
        directive fallback list</a> on |directive name|.

    1.  [=For each=] |name| in |fallback chain|:

        1.  If |policy|'s [=policy/directive set=] [=set/contains=] a
            [=directive=] |directive| whose [=directive/name=] is |name|,
            return |directive|.

    1.  Return null.
</ol>
</div>

### Does a policy sufficiently mitigate plugins? ### {#csp-plugin-mitigation}

<div algorithm="object requirements">
A [=policy=] |policy| <dfn for="policy">sufficiently mitigates plugins</dfn> if
the following algorithm returns "`Sufficient`". Possible return values are
"`Sufficient`" and "`Not sufficient`".

<ol class="algorithm">
    1.  <a abstract-op lt="obtain-directive">Obtain</a> |active directive| from
        |policy|, given "`object-src`".

    1.  Return "`Sufficient`" if all of the following are true:

        *   |active directive| is not null
        *   |active directive|'s [=directive/value=]'s [=set/size=] is 1
        *   |active directive|'s [=directive/value=][0] is an
            [=ASCII case-insensitive=] match for the string
            "<a grammar>`'none'`</a>".

    1.  Return "`Not sufficient`".
</ol>
</div>

### Does a policy sufficiently mitigate relative URL manipulation? ### {#csp-relative-url}

<div algorithm="base requirements">
A [=policy=] |policy| <dfn for="policy">sufficiently mitigates relative URL
manipulation</dfn> if the following algorithm returns "`Sufficient`".
Possible return values are "`Sufficient`" and "`Not sufficient`".

<ol class="algorithm">
    1.  [=For each=] |directive| in |policy|'s [=policy/directive set=]:

        1.  Return "`Sufficient`" if all of the following are true:

            *   |directive|'s [=directive/name=] is "`base-uri`".
            *   |directive|'s [=directive/value=]'s [=set/size=] is 1
            *   |directive|'s [=directive/value=][0] is an
                [=ASCII case-insensitive=] match for either the string
                "<a grammar>`'none'`</a>" or the string "<a grammar>`'self'`</a>".

    1.  Return "`Not sufficient`".
</ol>
</div>

### Does a policy sufficiently mitigate script execution? ### {#csp-script-mitigation}

<div algorithm="script requirements">
A [=policy=] |policy| <dfn for="policy">sufficiently mitigates script execution</dfn>
if the following algorithm returns "`Sufficient`".
Possible return values are "`Sufficient`" and "`Not sufficient`".

<ol class="algorithm">
    1.  <a abstract-op lt="obtain-directive">Obtain</a> |active directive| from
        |policy|, given "`script-src`".

    1.  Return "`Sufficient`" if all of the following are true:

        *   |active directive| is not null
        *   All [=source expressions=] in |active directive| are an
            [=ASCII case-insensitive=] match for the strings
            "<a grammar>`'none'`</a>", "<a grammar>`'self'`</a>", or
            "<a grammar>`'wasm-unsafe-eval'`</a>".

    1.  Return "`Not sufficient`".
</ol>
</div>

### Does a policy sufficiently mitigate style evaluation? ### {#csp-style-mitigation}

<div algorithm="style requirements">
A [=policy=] |policy| <dfn for="policy">sufficiently mitigates style evaluation</dfn> if
the following algorithm returns "`Sufficient`".
Possible return values are "`Sufficient`" and "`Not sufficient`".

<ol class="algorithm">
    1.  [=For each=] |directive| in |policy|'s [=policy/directive set=]:
        1.  <a abstract-op lt="obtain-directive">Obtain</a> |active directive| from
            |policy|, given "`style-src`".

        1.  Return "`Sufficient`" if all of the following are true:

            *   |directive|'s [=directive/name=] is "`style-src`".
            *   All [=source expressions=] in |active directive| are an
                [=ASCII case-insensitive=] match for the strings
                "<a grammar>`'none'`</a>", "<a grammar>`'self'`</a>", or
                "<a grammar>`'unsafe-inline'`</a>".

    1.  Return "`Not sufficient`".
</ol>
</div>

### Does a policy sufficiently block insecure subresources? ### {#csp-subresources}

<div algorithm="subresource requirements">
A [=policy=] |policy| <dfn for="policy">sufficiently blocks insecure
subresources</dfn> if the following algorithm returns "`Sufficient`".
Possible return values are "`Sufficient`" and "`Not sufficient`".

<ol class="algorithm">
    1.  [=For each=] |directive name| in the set [`frame-src`, `connect-src`,
        `img-src`, `media-src`, `font-src`]:
        1.  <a abstract-op lt="obtain-directive">Obtain</a> |active directive|
            from |policy|, given |directive name|.

        1.  Return "`Not sufficient`" if any [=source expression=] in
            |active directive| is **not** an [=ASCII case-insensitive=] match
            for the strings "<a grammar>`'none'`</a>", "<a grammar>`'self'`</a>",
            "`https:`", "`blob:`", or "`data:`".

    1.  Return "`Sufficient`"
</ol>
</div>

### Does a policy sufficiently mitigate DOM sinks? ### {#csp-sink-mitigation}

<div algorithm="trusted type requirements">
A [=policy=] |policy| <dfn for="policy">sufficiently mitigates DOM sinks</dfn>
if the following algorithm returns "`Sufficient`".
Possible return values are "`Sufficient`" and "`Not sufficient`".

<ol class="algorithm">
    1.  [=For each=] |directive| in |policy|'s [=policy/directive set=]:

        1.  Return "`Sufficient`" if all of the following are true:

            *   |directive|'s [=directive/name=] is
                "<code>[=require-trusted-types-for-directive|require-trusted-types-for=]</code>".
                [[!TRUSTED-TYPES]]
            *   |directive|'s [=directive/value=] [=set/contains=][0] an
                [=ASCII case-insensitive=] match for the string "`'script'`".

    1.  Return "`Not sufficient`".
</ol>
</div>

### Example ### {#csp-example}

The following CSP
<a for="CSP list" lt="mitigate-injection">meaningfully mitigates injection
attacks</a>:

<pre class="example">
base-uri 'none';
default-src 'self';
object-src 'none';
script-src 'self' 'wasm-unsafe-eval';
style-src 'self' 'unsafe-inline';
frame-src 'self' https: blob: data:;
connect-src 'self' https: blob: data:;
img-src 'self' https: blob: data:;
media-src 'self' https: blob: data:;
font-src 'self' blob: data:;
require-trusted-types-for 'script';
</pre>

### Does a policy meaningfully mitigate UI Redressing attacks? ### {#csp-ui-redressing-mitigation}

<div algorithm="meaningfully mitigates ui redressing">
A [=CSP list=] |policies| is said to
<dfn for="CSP list" export local-lt="mitigate-ui-redressing">meaningfully
mitigate UI Redressing attacks</dfn> [[UISECURITY]] if the following algorithm
returns "`Meaningful`".
Possible return values are "`Meaningful`" and "`Not meaningful enough`".

<ol class="algorithm">
    1.  [=For each=] |policy| in |policies|:

        1.  If |policy|'s [=policy/disposition=] is not "`enforce`" or
            |policy|'s [=policy/source=] is not "`header`",
            [=iteration/continue=].

        1.  [=For each=] |directive| in |policy|'s [=policy/directive set=]:

            1.  Return "`Meaningful`" if all of the following are true:

                *   |directive|'s [=directive/name=] is "`frame-ancestors`".
                *   |directive|'s [=directive/value=]'s [=set/size=] is 1
                *   |directive|'s [=directive/value=][0] is an
                    [=ASCII case-insensitive=] match for either the string
                    "<a grammar>`'none'`</a>" or the string "<a grammar>`'self'`</a>".

    1. Return "`Not meaningful enough`".
</ol>
</div>


## HTML ## {#monkey-html}

In HTML, we'll define a few properties used for resource integrity verification,
and some algorithms used in combination with those defined in
[[#monkey-csp]] to define characteristics of the
[=environment settings object=]. These characteristics will be examined from
[[WEBIDL]] when determining whether or not a given IDL construct is exposed on
the associated [=environment settings object/global object=].

### Integrity ### {#html-integrity}

An <dfn export>integrity verification algorithm</dfn> is an
[=implementation-defined=] algorithm that accepts a [=request=] and a
[=response=], and returns a [=boolean=].

Note: A typical [=integrity verification algorithm=] might verify that a
response body hashes to an expected value, or that it originated from a known
bundle of resources.

A [=user agent=] holds an <dfn export>origin integrity verification map</dfn>,
which is a [=map=] of [=tuple origins=] to
[=integrity verification algorithms=].

Note: How user agents populate the [=origin integrity verification map=] is
outside the scope of this specification, which is focused on the properties
needed to establish integrity and isolation.
<a href="https://github.com/WICG/isolated-web-apps/">Isolated Web Apps</a>
provide one possible implementation by basing this map on the set of installed
Isolated Web Apps.

### Environment Settings Object properties ### {#html-environment-properties}

<div algorithm="environment settings object mitigates injection">
An [=environment settings object=] is said to
<dfn for="environment settings object" export>meaningfully mitigate injection
attacks</dfn> if its [=environment settings object/policy container=]'s
[=policy container/CSP list=] <a for="CSP list" lt="mitigate-injection">
meaningfully mitigates injection attacks</a>.
</div>

<div algorithm="environment settings object mitigates ui redressing">
An [=environment settings object=] is said to
<dfn for="environment settings object" export>mitigate UI Redressing attacks
</dfn> if its [=environment settings object/policy container=]'s
[=policy container/CSP list=] <a for="CSP list" lt="mitigate-ui-redressing">
meaningfully mitigates UI Redressing attacks</a>.
</div>

Note: Because the definition of meaningful injection and UI Redressing
mitigation for a CSP list depends only upon the header-delivered policies,
these properties will not mutate during an environment's lifetime.

<div algorithm="environment settings object is an isolated context">
An [=environment settings object=] |environment| is an
<dfn export>isolated context</dfn> if the following algorithm returns `true`:
    1.  If |environment| does not [=environment settings object/meaningfully
        mitigate injection attacks=], return `false`.
    1.  If |environment|'s [=cross-origin isolated capability=] is
        not [=concrete=], return `false`.
    1.  If |environment| does not [=environment settings object/mitigate UI
        Redressing attacks=], return `false`.
    1.  Let |origin| be |environment|'s [=origin=].
    1.  If the [=user agent=]'s [=origin integrity verification map=][|origin|]
        does not [=map/exist=], return `false`.
    1.  Return `true`.
</div>


## Fetch ## {#monkey-fetch}

In Fetch, we'll use the [=integrity verification algorithm=] defined in
[[#html-integrity]] to verify that responses have the expected contents.

### Verify the integrity of a response ### {#fetch-verify-response}
<div algorithm>
To <dfn>verify the integrity of a response</dfn> given a [=request=] |request|
and a [=response=] |response|, run these steps. Possible return values are
"`not applicable`", "`invalid`", or "`valid`".

<ol>
  <li>Let |client| be |request|'s [=request/client=].</li>
  <li>If |client| is `null`, return "`not applicable`".</li>
  <li>Let |origin| be |request|'s [=request/origin=].</li>
  <li>
    If the [=user agent=]'s [=origin integrity verification map=][|origin|]
    does not [=map/exist=], return "`not applicable`".
  </li>
  <li>
    Let |integrity verification algorithm| be the [=user agent=]'s
    [=origin integrity verification map=][|origin|].
  </li>
  <li>
    If |response|'s [=response/body=] is `null`, return "`invalid`".
  </li>
  <li>
    If the result of executing |integrity verification algorithm| given
    |request| and |response| is `false`, return "`invalid`".
  </li>
  <li>
    Return "`valid`".
  </li>
</ol>
</div>

### Patches to the "Main Fetch" algorithm ### {#fetch-main-fetch}
The [=main fetch=] algorithm is extended as follows:

<div>
To <strong id="monkey-main-fetch">main fetch</strong>, given a
[=fetch params=] |fetchParams| and an optional boolean
<var ignore>recursive</var> (default false), run these steps:

<ol>
  <li>Let |request| be |fetchParams|'s [=fetch params/request=].</li>
  <li>Let |response| be `null`.</li>
  <li value="22">
    If |request|'s [=integrity metadata=] is not the empty string, then:
    <ol><li>...</li></ol>
  </li>
  <li><ins>
    If the result of executing [=verify the integrity of a response=] given
    |request| and |response| is "`invalid`", then run
    <a href="https://fetch.spec.whatwg.org/#fetch-finale">fetch response
    handover</a> given |fetchParams| and a [=network error=].
  </ins></li>
  <li>
    Otherwise, run <a href="https://fetch.spec.whatwg.org/#fetch-finale">fetch
    response handover</a> given |fetchParams| and |response|.
  </li>
</ol>
</div>

NOTE: Ideally we would integrate integrity verification with [[SRI]]'s
[=integrity metadata=] and its supporting algorithms. That would require a
non-trivial refactoring of how the [[SRI]] specification handles
[=integrity metadata=] strings, which may be worth pursuing in the future.


## WebIDL ## {#monkey-webidl}

In WebIDL, we'll define the `[IsolatedContext]` attribute, and wire it up to
the hook created in HTML above:

<h4 id="IsolatedContext" extended-attribute lt="IsolatedContext">
  [IsolatedContext]
</h4>

If the [{{IsolatedContext}}] [=extended attribute=] appears on an
[=interface=],
[=partial interface=],
[=interface mixin=],
[=partial interface mixin=],
[=callback interface=],
[=namespace=],
[=partial namespace=],
[=interface member=],
[=interface mixin member=], or
[=namespace member=],
it indicates that the construct is [=exposed=]
only within an [=isolated context=].
The [{{IsolatedContext}}] extended attribute must not be used
on any other construct.

The [{{IsolatedContext}}] extended attribute must
[=takes no arguments|take no arguments=].

If [{{IsolatedContext}}] appears on an [=overloaded=] [=operation=],
then it must appear on all overloads.

The [{{IsolatedContext}}] [=extended attribute=] must not be specified on more
than one of the following:

* an [=interface member=] and its [=interface=] or [=partial interface=];
* an [=interface mixin member=] and its [=interface mixin=] or
    [=partial interface mixin=];
* a [=namespace member=] and its [=namespace=] or [=partial namespace=].

Note: This is because adding the [{{IsolatedContext}}] [=extended attribute=]
on a [=member=] when its containing definition is also annotated with the
[{{IsolatedContext}}] [=extended attribute=] does not further restrict the
exposure of the [=member=].

An [=interface=] without the [{{IsolatedContext}}] [=extended attribute=]
must not [=interface/inherit=] from another interface
that does specify [{{IsolatedContext}}].

### Patches to the "exposed" algorithm ### {#monkey-webidl-exposed}

WebIDL's [=exposed=] algorithm is adjusted as follows, adding a single step
after similarly handling [{{CrossOriginIsolated}}] (step 4 below).

<div>
  An [=interface=], [=callback interface=], [=namespace=], or [=member=]
  |construct| is <strong id="dfn-exposed" export>exposed</strong> in a given
  [=realm=] |realm| if the following steps return true:

  <ol>
    <li>
      If |construct|'s [=exposure set=] is not <code>*</code>, and
      |realm|.\[[GlobalObject]] does not implement an [=interface=] that is in
      |construct|'s [=exposure set=], then return false.
    </li>
    <li>
      If |realm|'s [=realm/settings object=] is not a [=secure context=], and
      |construct| is [=conditionally exposed=] on [{{SecureContext}}], then
      return false.
    </li>
    <li>
      If |realm|'s [=realm/settings object=]'s
      [=environment settings object/cross-origin isolated capability=] is false,
      and |construct| is [=conditionally exposed=] on [{{CrossOriginIsolated}}],
      then return false.
    </li>
    <li><ins>
        If |realm|'s [=realm/settings object=] is not an [=isolated context=],
        and |construct| is [=conditionally exposed=] on [{{IsolatedContext}}],
        then return `false`.
    </ins></li>
    <li>Return true.</li>
  </ol>
</div>


## Storage ## {#monkey-storage}

The [=obtain a storage key for non-storage purposes=] algorithm is extended to
require double-keying on all storage belonging to an
<a href="https://html.spec.whatwg.org/multipage/webappapis.html#environment">
environment</a> with a [=top-level origin=] known by the [=user agent=] to have
an [=integrity verification algorithm=].

<div algorithm="obtain a storage key for non-storage purposes isolated context">
To obtain a storage key for non-storage purposes, given an
<a href="https://html.spec.whatwg.org/multipage/webappapis.html#environment">
environment</a> |environment|, run these steps:

<ol>
    <li>
      Let |origin| be |environment|'s [=environment settings object/origin=] if
      |environment| is an [=environment settings object=]; otherwise
      |environment|'s [=creation URL=]'s [=origin=].
    </li>

    <li><ins>
      Let |top-level origin| be |environment|'s [=top-level origin=].
    </ins></li>
    <li><ins>
      If the [=user agent=]'s [=origin integrity verification map=]
      [|top-level origin|] [=map/exists=], return a [=tuple=] consisting of
      |top-level origin| and |origin|.
    </ins></li>

    <li>
      Return a [=tuple=] consisting of |origin|.
    </li>
</ol>
</div>

Note: This is essentially a minimally-specified version of
<a href="https://privacycg.github.io/storage-partitioning/">
Client-Side Storage Partitioning</a>. When that is fully specified and merged
into the necessary specifications, those changes will supersede this section,
and it can be removed.
